﻿#pragma once

namespace ifire {

template <int N> class VecN {
private:
  float data[N]; // 静态数组存储数据

public:
  // 构造函数
  VecN() {
    static_assert(N > 0, "Vector dimension must be positive");
    Zero();
  }

  // 拷贝构造（新增）
  VecN(const VecN& other) { std::copy(other.data, other.data + N, data); }

  // 拷贝赋值（新增）
  VecN& operator=(const VecN& other) {
    if (this != &other) {
      std::copy(other.data, other.data + N, data);
    }
    return *this;
  }

  // 允许移动
  VecN(VecN&&) = default;
  VecN& operator=(VecN&&) = default;

  // 向量置零
  void Zero() {
    for (int i = 0; i < N; ++i) {
      data[i] = 0.0f;
    }
  }

  // 向量点积
  float Dot(const VecN& v) const noexcept {
    float sum = 0.0f;
    for (int i = 0; i < N; ++i) {
      sum += data[i] * v.data[i];
    }
    return sum;
  }

  // 向量加法
  VecN operator+(const VecN& v) const {
    VecN result;
    for (int i = 0; i < N; ++i) {
      result[i] = data[i] + v.data[i];
    }
    return result;
  }

  // 向量减法
  VecN operator-(const VecN& v) const {
    VecN result;
    for (int i = 0; i < N; ++i) {
      result[i] = data[i] - v.data[i];
    }
    return result;
  }

  // 向量数乘
  VecN operator*(float scalar) const {
    VecN result;
    for (int i = 0; i < N; ++i) {
      result[i] = data[i] * scalar;
    }
    return result;
  }

  // 向量加法赋值
  VecN& operator+=(const VecN& v) {
    for (int i = 0; i < N; ++i) {
      data[i] += v.data[i];
    }
    return *this;
  }

  // 向量减法赋值
  VecN& operator-=(const VecN& v) {
    for (int i = 0; i < N; ++i) {
      data[i] -= v.data[i];
    }
    return *this;
  }

  // 向量数乘赋值
  VecN& operator*=(float scalar) {
    for (int i = 0; i < N; ++i) {
      data[i] *= scalar;
    }
    return *this;
  }

  // 元素访问（const）
  float operator[](int index) const {
    static_assert(N > 0, "Vector must have positive dimension");
    return data[index];
  }

  // 元素访问（非const）
  float& operator[](int index) {
    static_assert(N > 0, "Vector must have positive dimension");
    return data[index];
  }

  // 获取向量维度（编译期常量）
  static constexpr int Size() { return N; }
};

} // namespace ifire